package com.itheima.aspect;

import com.alibaba.fastjson.JSONObject;
import com.itheima.Util.JwtUtil;
import com.itheima.dao.EmpMapper;
import com.itheima.dao.LogMapper;
import com.itheima.pojo.Emp;
import com.itheima.pojo.Log;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

/**
 * 日志切面类
 */
//标识切面类(来自导入的SpringAOP依赖)
@Aspect
//将javabean变成springbean
@Component
@Slf4j
public class LogAspect {
    //注入mapper,用于将数据插入日志表中
    @Resource
    LogMapper logMapper;
    //注入mapper,用于查询操作人的信息
    @Resource
    EmpMapper empMapper;
    //注入request,用于获取请求头中的token,
    //并解析操作人信息(Spring中自动创建的东西都可以通过@Resource取)
    @Resource
    HttpServletRequest request;

    @Around("@annotation(com.itheima.annotation.Log)")
    //point 代指要增强的方法
    public Object insertLog(ProceedingJoinPoint point){

        try {
            // 开始时间
            long start = System.currentTimeMillis();
            // 执行父类方法
            Object proceed = point.proceed();
            // 结束时间
            long end = System.currentTimeMillis();
            // 总耗时
            long time = end - start;

            // 从请求头中获取token,并读取token中的信息,查询数据库,返回操作人的信息
            String token = request.getHeader("token");
            JSONObject jsonObject = JwtUtil.checkToken(token);
            Emp login = empMapper.login(jsonObject.getString("username"));
            // 实例化日志对象
            Log.LogBuilder logBuilder = Log.builder();
            Log build = logBuilder
                    .operateEmpId(login.getId())
                    .operateEmpName(login.getName())
                    .operateTime(LocalDateTime.now())
                    .className(point.getTarget().getClass().getName())
                    .methodName(point.getSignature().getName())
                    .costTime(time)
                    .methodParams(JSONObject.toJSONString(point.getArgs()))
                    .returnValue(JSONObject.toJSONString(proceed))
                    .build();
            log.info("日志记录成功{}",build);
            // 调用LogMapper中的插入方法,将数据存入数据库中
            logMapper.insert(build);
            return proceed;
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }

    }


}
